package com.zhihu.matisse.provider;

import com.zhihu.matisse.MimeType;
import com.zhihu.matisse.ResourceTable;
import com.zhihu.matisse.component.CheckView;
import com.zhihu.matisse.model.*;
import com.zhihu.matisse.utils.L;
import com.zhihu.matisse.utils.TimeUtils;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.ability.DataAbilityRemoteException;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.app.Context;
import ohos.media.photokit.metadata.AVMetadataHelper;
import ohos.media.photokit.metadata.AVStorage;
import ohos.utils.net.Uri;

import java.io.FileNotFoundException;
import java.util.ArrayList;

public class MediaProvider extends BaseItemProvider {

    private final ArrayList<Item> list;
    private final Context mContext;
    private final SelectedItemCollection mCollection;
    private final SelectionSpec selectionSpec;
    private CheckStateListener mCheckStateListener;
    private OnMediaClickListener mOnMediaClickListener;

    private final ShapeElement mPlaceholder;
    private final ShapeElement gradientElement;

    private int spanCount = 1;
    private int mImageResize = 0;
    private int mImageWidth = 0;

    public MediaProvider(Context context, ArrayList<Item> list, SelectedItemCollection collection,int spanCount) {
        selectionSpec = SelectionSpec.getInstance();
        this.list = list;
        mContext = context;
        mCollection = collection;
        this.spanCount = spanCount;

        mPlaceholder = new ShapeElement();
        mPlaceholder.setRgbColor(RgbColor.fromArgbInt(context.getColor(ResourceTable.Color_zhihu_item_placeholder)));

        gradientElement = new ShapeElement();
        gradientElement.setGradientOrientation(ShapeElement.Orientation.TOP_TO_BOTTOM);
        gradientElement.setShaderType(ShapeElement.LINEAR_GRADIENT_SHADER_TYPE);
        gradientElement.setRgbColors(new RgbColor[]{RgbColor.fromArgbInt(0x00A7A7A7),RgbColor.fromArgbInt(0x2FA7A7A7)});
    }

    @Override
    public int getCount() {
        return list == null ? 0 : list.size();
    }

    @Override
    public Object getItem(int i) {
        return list.get(i);
    }

    @Override
    public long getItemId(int i) {
        return list == null ? 0 : list.get(i).hashCode();
    }

    public ArrayList<Item> getList() {
        return list;
    }



    @Override
    public Component getComponent(int i, Component component, ComponentContainer componentContainer) {

        MediaHolder mediaHolder;
        Component v;
        if (component == null){
            v = LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_media_grid_layout, componentContainer, false);
            mediaHolder = new MediaHolder(v);
            v.setTag(mediaHolder);
        }else {
            v = component;
            mediaHolder = (MediaHolder) v.getTag();
        }


        ComponentContainer.LayoutConfig layoutConfig = new ComponentContainer.LayoutConfig(getImageWidth(),getImageWidth());
        layoutConfig.setMarginBottom(AttrHelper.vp2px(4,mContext));
        layoutConfig.setMarginRight(AttrHelper.vp2px(4,mContext));
        v.setLayoutConfig(layoutConfig);


        Item item= (Item) getItem(i);
        mediaHolder.duration.setBubbleElement(gradientElement);
        if (item.id < 0){
            mediaHolder.image.setVisibility(Component.HIDE);
            mediaHolder.checkView.setVisibility(Component.HIDE);
            mediaHolder.duration.setVisibility(Component.HIDE);
            mediaHolder.gif.setVisibility(Component.HIDE);
            mediaHolder.tvCamera.setVisibility(Component.VISIBLE);


        }else {
            mediaHolder.image.setVisibility(Component.VISIBLE);
            mediaHolder.checkView.setVisibility(Component.VISIBLE);
            mediaHolder.tvCamera.setVisibility(Component.HIDE);
            mediaHolder.checkView.setCountable(selectionSpec.countable);

            if (MimeType.isImage(item.mimeType)) {
                Uri uri = Uri.appendEncodedPathToUri(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, String.valueOf(item.id));
                if (MimeType.isGif(item.mimeType)) {
                    mediaHolder.gif.setVisibility(Component.VISIBLE);
                    selectionSpec.imageEngine.loadGifThumbnail(mContext,getImageResize(mContext),mPlaceholder,mediaHolder.image,uri);
                } else {
                    mediaHolder.gif.setVisibility(Component.HIDE);
                    selectionSpec.imageEngine.loadThumbnail(mContext,getImageResize(mContext),mPlaceholder,mediaHolder.image,uri);
                }
                mediaHolder.duration.setVisibility(Component.HIDE);
            } else if (MimeType.isVideo(item.mimeType)) {
                mediaHolder.gif.setVisibility(Component.HIDE);
                mediaHolder.duration.setVisibility(Component.VISIBLE);
                Uri uri = Uri.appendEncodedPathToUri(AVStorage.Video.Media.EXTERNAL_DATA_ABILITY_URI, String.valueOf(item.id));
                mediaHolder.duration.setText(TimeUtils.formatElapsedTime(item.duration / 1000));
                selectionSpec.imageEngine.loadThumbnail(mContext,getImageResize(mContext),mPlaceholder,mediaHolder.image,uri);
            }
            mediaHolder.checkView.setClickedListener(component12 -> updateSelectedItem(item,mContext));
            setCheckStatus(item,mediaHolder.checkView);
        }
        v.setClickedListener(component1 -> {
            if (item.isCapture()){
                if (mOnMediaClickListener != null) {
                    mOnMediaClickListener.onMediaSelect(null, item, i);
                }
            }else {
                if (selectionSpec.showPreview){
                    if (mOnMediaClickListener != null) {
                        mOnMediaClickListener.onMediaSelect(null, item, i);
                    }
                }else {
                    updateSelectedItem(item,mContext);
                }
            }

        });
        return v;
    }
    private int getImageWidth(){
        if (mImageWidth == 0){
            int screenWidth = AttrHelper.fp2px(mContext.getResourceManager().getDeviceCapability().width,mContext);
            int availableWidth = screenWidth - AttrHelper.vp2px(4 * (spanCount - 1),mContext);
            mImageWidth = availableWidth / spanCount;
        }
        return mImageWidth;
    }
    private int getImageResize(Context context){
        if (mImageResize == 0){
            int spanCount = selectionSpec.spanCount;
            int screenWidth = AttrHelper.fp2px(context.getResourceManager().getDeviceCapability().width,context);
            int availableWidth = screenWidth - AttrHelper.vp2px(4 * (spanCount - 1),context);
            mImageResize = availableWidth / spanCount;
            mImageResize = (int) (mImageResize * selectionSpec.thumbnailScale);
        }
        return mImageResize;
    }

    private void setCheckStatus(Item item,CheckView checkView){
        if (selectionSpec.countable){
            int checkNum = mCollection.checkedNumOf(item);
            if (checkNum > 0){
                checkView.setEnabled(true);
                checkView.setCheckedNum(checkNum);
            }else {
                if (mCollection.maxSelectableReached()){
                    checkView.setEnabled(false);
                    checkView.setCheckedNum(CheckView.UNCHECKED);
                }else {
                    checkView.setEnabled(true);
                    checkView.setCheckedNum(checkNum);
                }
            }
        }else {
            boolean selected = mCollection.isSelected(item);
            if (selected) {
                checkView.setEnabled(true);
                checkView.setChecked(true);
            } else {
                if (mCollection.maxSelectableReached()) {
                    checkView.setEnabled(false);
                    checkView.setChecked(false);
                } else {
                    checkView.setEnabled(true);
                    checkView.setChecked(false);
                }
            }
        }
    }
    private void updateSelectedItem(Item item,Context holder) {
        if (selectionSpec.countable) {
            int checkedNum = mCollection.checkedNumOf(item);
            if (checkedNum == CheckView.UNCHECKED) {
                if (assertAddSelection(holder, item)) {
                    mCollection.add(item);
                    notifyCheckStateChanged();
                }
            } else {
                mCollection.remove(item);
                notifyCheckStateChanged();
            }
        } else {
            if (mCollection.isSelected(item)) {
                mCollection.remove(item);
                notifyCheckStateChanged();
            } else {
                if (assertAddSelection(holder, item)) {
                    mCollection.add(item);
                    notifyCheckStateChanged();
                }
            }
        }
    }
    public void registerOnMediaClickListener(OnMediaClickListener listener) {
        mOnMediaClickListener = listener;
    }

    public void unregisterOnMediaClickListener() {
        mOnMediaClickListener = null;
    }
    public void registerCheckStateListener(CheckStateListener listener) {
        mCheckStateListener = listener;
    }

    public void unregisterCheckStateListener() {
        mCheckStateListener = null;
    }
    private void notifyCheckStateChanged() {
        notifyDataChanged();
        if (mCheckStateListener != null) {
            mCheckStateListener.onUpdate();
        }
    }
    private boolean assertAddSelection(Context context, Item item) {
        IncapableCause cause = mCollection.isAcceptable(item);
        IncapableCause.handleCause(context, cause);
        return cause == null;
    }
    public interface CheckStateListener {
        void onUpdate();
    }
    public interface OnMediaClickListener {
        void onMediaSelect(Album album, Item item, int adapterPosition);
    }

    public class MediaHolder{
        Image image;
        Text duration;
        Image gif;
        CheckView checkView;
        Text tvCamera;

        MediaHolder(Component v){
             image = (Image) v.findComponentById(ResourceTable.Id_media_thumbnail);
             duration = (Text) v.findComponentById(ResourceTable.Id_media_duration);
             gif = (Image) v.findComponentById(ResourceTable.Id_media_gif);
             checkView = (CheckView) v.findComponentById(ResourceTable.Id_media_check);
             tvCamera = (Text) v.findComponentById(ResourceTable.Id_media_camera);
        }
    }
}
